// #ifdef APP-PLUS || H5
// ----------------------------------------------------
// App 和 H5 环境下的完整版 Vuex IM 模块
// ----------------------------------------------------


import imService from '@/utils/imService.js'; // 引入我们封装的imService
import {
	EasemobSDK
} from '@/EaseIM/index.js'; // 引入SDK本身，可能用于状态码等
// 引入后端API
import {
	getPrivateRead,
	getConversationList,
	getTotalUnreadCount
} from '@/request/api.js';

const state = {
	appKey: '',
	imConfig: null,
	isConnected: false,
	isLoggingIn: false,
	loginError: null,
	imUserId: null,
	imToken: null, // 环信登录用的token/密码
	imAppToken: uni.getStorageSync('im_app_token') || null, // 存储IM App Token
	conversations: uni.getStorageSync(
	'conversations'), // { id, type, lastMessage, unreadCount, timestamp, name, avatar }
	// 新增：从后端获取的会话列表，用于UI展示
	sessionList: uni.getStorageSync('sessionList') || [],
	// 未读总数
	totalUnreadCount: uni.getStorageSync('totalUnreadCount') || 0,
};

const mutations = {
	SET_IM_CONFIG(state, config) {
		state.imConfig = config;
		if (config && config.appKey) {
			state.appKey = config.appKey;
		}
	},
	SET_CONNECTED(state, status) {
		state.isConnected = status;
	},
	SET_LOGGING_IN(state, status) {
		state.isLoggingIn = status;
	},
	SET_LOGIN_ERROR(state, error) {
		state.loginError = error;
	},
	SET_IM_USER(state, {
		userId,
		token
	}) {
		state.imUserId = userId;
		state.imToken = token;
	},
	SET_IM_APP_TOKEN(state, token) {
		state.imAppToken = token;
		uni.setStorageSync('im_app_token', token);
	},
	CLEAR_IM_USER(state) {
		state.imUserId = null;
		state.imToken = null;
		state.isConnected = false;
		state.imAppToken = null; // 登出时也要清除
		uni.removeStorageSync('im_app_token');
	},
	// 更新会话列表 (这是一个基础版本，实际项目中会更复杂)
	UPDATE_CONVERSATIONS(state, newConversations) {
		// 简单替换，实际应用中可能需要合并、排序等
		state.conversations = newConversations.map(conv => ({
			id: conv.conversationId || conv.id, // SDK返回的会话ID字段可能不同
			type: conv.chatType || conv.type, // 'singleChat', 'groupChat'
			unreadCount: conv.unreadCount || 0,
			lastMessage: conv.lastMessage ? {
				id: conv.lastMessage.id,
				from: conv.lastMessage.from,
				to: conv.lastMessage.to,
				data: conv.lastMessage.type == 'txt' ? conv.lastMessage.msg || conv.lastMessage
					.data : (conv.lastMessage.type === 'img' ? '[图片]' : '[消息]'), // 适配不同SDK的消息体
				type: conv.lastMessage.type,
				timestamp: conv.lastMessage.time || conv.lastMessage.timestamp,
			} : null,
			timestamp: conv.lastMessage ? (conv.lastMessage.time || conv.lastMessage.timestamp) : (conv
				.time || Date.now()),
			// name 和 avatar 需要从其他地方获取（如好友列表、群信息）
			name: conv.name || conv.conversationId || conv.id,
			avatar: conv.avatar || (conv.chatType === 'groupChat' ? '/static/group_avatar.png' :
				'/static/default_avatar.png')
		})).sort((a, b) => b.timestamp - a.timestamp);
		if (state.conversations.length == 0) {
			state.conversations = uni.getStorageSync('conversations')
		} else {
			uni.setStorage({
				key: 'conversations',
				data: state.conversations
			})
		}
	},
	// 新增：用于更新后端会话列表的 mutation
	SET_SESSION_LIST(state, sessions) {
		state.sessionList = sessions;
		// 将会话列表持久化到本地存储
		uni.setStorageSync('sessionList', sessions);
	},
	// 新增：用于设置未读总数的 mutation
	SET_TOTAL_UNREAD_COUNT(state, count) {
		state.totalUnreadCount = count;
		uni.getStorageSync('totalUnreadCount', state.totalUnreadCount)
	},
	ADD_OR_UPDATE_CONVERSATION(state, message) { // 当收到新消息时调用
		const conversationId = message.chatType === 'singleChat' ? (message.from === state.imUserId ? message.to :
			message.from) : message.to;
		const existingConvIndex = state.conversations.findIndex(c => c.id === conversationId);

		let convData = {
			id: conversationId,
			type: message.chatType,
			lastMessage: {
				id: message.id,
				from: message.from,
				to: message.to,
				data: message.type === 'txt' ? message.data || message.msg : (message.type === 'img' ? '[图片]' :
					`[${message.type}]`),
				type: message.type,
				timestamp: message.time || Date.now(),
			},
			timestamp: message.time || Date.now(),
			// name, avatar 需要从其他地方填充
			name: conversationId, // 临时用ID
			avatar: message.chatType === 'groupChat' ? '/static/group_avatar.png' :
				'/static/default_avatar.png', // 临时头像
		};
		if (existingConvIndex > -1) {
			convData.unreadCount = (state.conversations[existingConvIndex].unreadCount || 0) + 1;
			// 如果应用在前台且当前聊天对象是此会话，则不增加未读数 (这部分逻辑通常在聊天页面处理)
			state.conversations.splice(existingConvIndex, 1); // 先移除
		} else {
			convData.unreadCount = 1;
		}
		state.conversations.unshift(convData); // 插入到最前面
	},
	RESET_CONVERSATIONS(state) {
		state.conversations = [];
	},
	MARK_CONVERSATION_AS_READ(state, conversationId) {
		const conv = state.conversations.find(c => c.id === conversationId);
		if (conv) {
			conv.unreadCount = 0;
		}
	},
	ADD_MESSAGE_TO_CONVERSATION(state, {
		conversationId,
		message,
		isSelfSent = false
	}) {
		// 这个 mutation 应该被 `handleNewMessage` (接收消息) 和
		// `sendTextMessage` action (发送消息成功/失败) 调用来更新会话的 lastMessage 和 消息列表
		// 注意：聊天页面的消息列表通常独立于会话列表的 lastMessage
		// 你可能需要一个更细致的结构来存储每个会话的完整消息记录，例如:
		// state.chatMessages: { 'conversationId1': [msg1, msg2], 'conversationId2': [...] }
		// 或者，让聊天页面自己管理 messages 数组，只通过Vuex同步最后一条消息到conversations

		// 简单示例：只更新会话列表的 lastMessage
		const convIndex = state.conversations.findIndex(c => c.id === conversationId);
		const formattedLastMessage = {
			id: message.id || message.localId,
			from: message.from,
			to: message.to,
			data: message.content || message.data || (message.contentType === 'image' ? '[图片]' : '[消息]'),
			type: message.contentType || message.type, // 'text', 'image'
			timestamp: message.timestamp || message.time || Date.now(),
			status: message.status, // 'sending', 'sent', 'failed'
			quoteInfo: message.quoteInfo,
		};

		if (convIndex > -1) {
			state.conversations[convIndex].lastMessage = formattedLastMessage;
			state.conversations[convIndex].timestamp = formattedLastMessage.timestamp;
			if (!isSelfSent && message.from !== state.imUserId) { // 如果是对方发来的新消息
				state.conversations[convIndex].unreadCount = (state.conversations[convIndex].unreadCount || 0) + 1;
			}
			// 将更新的会话移到顶部
			const conv = state.conversations.splice(convIndex, 1)[0];
			state.conversations.unshift(conv);
		} else { // 新会话
			state.conversations.unshift({
				id: conversationId,
				type: message.chatType,
				lastMessage: formattedLastMessage,
				unreadCount: (isSelfSent || message.from === state.imUserId) ? 0 : 1,
				timestamp: formattedLastMessage.timestamp,
				name: conversationId, // 应从好友/群信息获取
				avatar: '/static/default_avatar.png', // 应从好友/群信息获取
			});
		}
	},

	UPDATE_MESSAGE_STATUS(state, {
		conversationId,
		localId,
		serverId,
		status
	}) {
		// 这个mutation用于更新本地发送消息的状态
		// 你需要一种方式在聊天页面的消息列表中找到对应的消息并更新其状态
		// 例如，如果聊天页面的消息列表也存在Vuex中：
		// const chat = state.chatMessages[conversationId];
		// if (chat) {
		//     const msgIndex = chat.findIndex(m => m.id === localId);
		//     if (msgIndex > -1) {
		//         chat[msgIndex].status = status;
		//         if (serverId) chat[msgIndex].serverId = serverId; // 存储服务器ID
		//     }
		// }

		// 更新会话列表中的 lastMessage (如果这条是最后一条消息)
		const conv = state.conversations.find(c => c.id === conversationId);
		if (conv && conv.lastMessage && conv.lastMessage.id === localId) {
			conv.lastMessage.status = status;
			if (serverId) conv.lastMessage.serverId = serverId;
		}
	}
};

const actions = {

	// 初始化IM (主要设置监听)
	async initIMCore({
		commit,
		dispatch,
		rootState
	}, config) { // rootState 可用于获取其他模块state
		commit('SET_IM_CONFIG', config); // 存储 appKey 等配置
		try {
			await imService.init(); // 调用 imService.js 中的 init 来设置监听器
			// --- 将事件监听的回调放在这里，直接commit mutations ---
			imService.eventBus.$off('im_opened'); // 先移除旧监听，防止重复
			imService.eventBus.$on('im_opened', () => {
				commit('SET_CONNECTED', true);
				commit('SET_LOGGING_IN', false);
				commit('SET_LOGIN_ERROR', null);
				// 自动登录成功后，可以尝试获取会话列表等
				// dispatch('fetchConversations');
				// 连接成功后，从后端拉取会话列表
				dispatch('fetchSessionList');
			});
			imService.eventBus.$off('im_closed');
			imService.eventBus.$on('im_closed', () => {
				commit('SET_CONNECTED', false);
			});

			imService.eventBus.$off('im_error');
			imService.eventBus.$on('im_error', (error) => {
				console.error("Vuex received IM Error:", error);
				// 细化错误处理，例如特定错误码代表认证失败
				if (error.type === EasemobSDK.statusCode.WEBIM_CONNCTION_AUTH_ERROR ||
					(error.data && error.data.type === EasemobSDK.statusCode.WEBIM_CONNCTION_AUTH_ERROR)
					) {
					commit('SET_LOGIN_ERROR', {
						message: "认证失败",
						...error
					});
					commit('SET_LOGGING_IN', false);
					commit('SET_CONNECTED', false);
					// 可能需要清除本地登录凭证
					dispatch('logout'); // 或者一个专门的 clearAuth action
				} else if (error.type === EasemobSDK.statusCode
					.WEBIM_CONNCTION_USER_LOGIN_ANOTHER_DEVICE) {
					// 被踢下线
					commit('SET_LOGIN_ERROR', {
						message: "账号在其他设备登录",
						...error
					});
					dispatch('logout'); // 强制登出
					uni.showToast({
						title: '您的账号已在其他设备登录',
						icon: 'none',
						duration: 3000
					});
					// 可能需要跳转到登录页
					uni.reLaunch({
						url: '/pages_sub/login/login'
					});
				} else {
					commit('SET_LOGIN_ERROR', error); // 其他错误
				}
			});

			imService.eventBus.$off('im_message_received');
			imService.eventBus.$on('im_message_received', (message) => {
				dispatch('handleNewMessage', message);
			});
			// --- 事件监听设置结束 ---

			// 尝试自动登录 (如果 SDK 本身 isAutoLogin: true 可能已处理，这里是应用层逻辑)
			// dispatch('tryAutoLogin'); // 暂时注释，依赖SDK的autoLogin

			return Promise.resolve();
		} catch (error) {
			console.error("Vuex: IM Service init failed in action", error);
			return Promise.reject(error);
		}
		console.log('初始化initIm', state.isConnected);
	},
	/**
	 * 新增: 进入会话页面的 Action
	 * 1. 调用接口将会话标记为已读
	 * 2. 立即重新获取会话列表以更新UI（如未读数）
	 * @param {string} targetUserId - 对方的用户ID
	 */
	async enterConversation({
		dispatch
	}, targetUserId) {
		if (!targetUserId) {
			console.error("[Vuex enterConversation] targetUserId 不能为空");
			return;
		}

		try {
			// 步骤1: 调用后端接口，将会话标记为已读
			await getPrivateRead(targetUserId);

			// 步骤2: 标记成功后，立即刷新整个会话列表
			// dispatch会触发 fetchSessionList action，从而更新 state.sessionList
			dispatch('fetchSessionList');
			dispatch('fetchTotalUnreadCount');

		} catch (error) {
			console.error(`[Vuex enterConversation] 处理进入会话时出错 (targetId: ${targetUserId}):`, error);
			// 即使标记已读失败，也尝试刷新一次列表，以防万一
			dispatch('fetchSessionList');
		}
	},

	// 新增：从后端API获取会话列表的 action
	async fetchSessionList({
		commit
	}) {
		try {
			const res = await getConversationList();
			if (res.data && res.data.code === 200) {
				// 后端返回的数据直接提交给 mutation
				commit('SET_SESSION_LIST', res.data.rows || []);
			} else {
				console.error("从后端获取会话列表失败:", res.data.msg);
			}
		} catch (error) {
			console.error("请求后端会话列表接口时出错:", error);
		}
	},
	// 新增：从后端API获取未读总数的 action
	async fetchTotalUnreadCount({
		commit
	}) {
		try {
			const res = await getTotalUnreadCount();
			if (res.data && res.data.code === 200) {
				// 将获取到的总数提交给 mutation
				commit('SET_TOTAL_UNREAD_COUNT', res.data.data);
			} else {
				console.error("从后端获取未读总数失败:", res.data.msg);
				commit('SET_TOTAL_UNREAD_COUNT', 0); // 出错时清零
			}
		} catch (error) {
			console.error("请求后端未读总数接口时出错:", error);
			commit('SET_TOTAL_UNREAD_COUNT', 0); // 出错时清零
		}
	},
	// 登录环信 (username 和 token/password 通常来自你的业务服务器)
	async login({
		commit,
		dispatch,
		state
	}, {
		username,
		token
	}) {

		console.log("登录环信", state);
		if (state.isLoggingIn || state.isConnected) {
			console.warn("Vuex: Already logging in or connected.");
			return Promise.resolve("Already logging in or connected.");
		}

		commit('SET_LOGGING_IN', true);
		commit('SET_LOGIN_ERROR', null);
		try {
			await imService.login(username, token);
			// 登录成功后，onOpened 事件会触发，更新 isConnected 和 isLoggingIn
			commit('SET_IM_USER', {
				userId: username,
				token
			});
			uni.setStorageSync('im_user_id', username);
			uni.setStorageSync('im_token', token); // 保存用于环信登录的token或密码

			/* 
			下面三行是从上面 initIMCore 监听中复制而来 imService.eventBus.$on('im_opened', () => {
                commit('SET_CONNECTED', true);
                commit('SET_LOGGING_IN', false);
                commit('SET_LOGIN_ERROR', null);
                // 自动登录成功后，可以尝试获取会话列表等
                dispatch('fetchConversations');
            });
			*/
			commit('SET_CONNECTED', true);
			commit('SET_LOGGING_IN', false);
			commit('SET_LOGIN_ERROR', null);
			// IM登录成功后，从后端拉取会话列表
			dispatch('fetchSessionList');
			dispatch('fetchTotalUnreadCount');
			// dispatch('fetchConversations');
			return Promise.resolve();
		} catch (error) {
			console.error("Vuex: IM Login failed in action", error);
			commit('SET_LOGIN_ERROR', error);
			commit('SET_LOGGING_IN', false);
			commit('SET_CONNECTED', false);
			uni.removeStorageSync('im_user_id');
			uni.removeStorageSync('im_token');
			return Promise.reject(error);
		}
	},

	// 登出环信
	async logout({
		commit
	}) {
		try {
			await imService.logout();
		} catch (error) {
			console.error("Vuex: IM Logout service call failed", error);
			// 即使服务调用失败，本地状态也应该清理
		} finally {
			commit('CLEAR_IM_USER');
			uni.removeStorageSync('im_user_id');
			uni.removeStorageSync('im_token');
			commit('RESET_CONVERSATIONS');
		}
	},

	// 处理新消息 (被 'im_message_received' 事件触发)
	handleNewMessage({
		commit,
		dispatch
	}, message) {
		// 这里可以保留对原生conversations的更新，也可以移除，取决于你是否还有其他地方需要它
		// commit('ADD_OR_UPDATE_CONVERSATION', message);
		// 可选：如果需要全局通知（如震动、声音），可以在这里处理或通过 getter 计算总未读数
		// 关键：收到新消息后，立即从后端重新拉取最新的会话列表
		setTimeout(() => {
			dispatch('fetchSessionList');
			dispatch('fetchTotalUnreadCount');
		}, 200)
	},

	// 获取会话列表
	async fetchConversations({
		commit
	}) {
		try {
			const conversations = await imService.getConversationsFromSDK();
			commit('UPDATE_CONVERSATIONS', conversations || []);
		} catch (error) {
			console.error("Vuex: Failed to fetch conversations", error);
		}
	},

	// 标记会话已读
	markConversationRead({
		commit,
		dispatch
	}, conversationId) {
		// 从后端会话列表(sessionList)中找到对应的会话
		const conv = state.sessionList.find(c => c.targetId === conversationId);

		// 如果找到了会话，并且有最后一条消息的信息
		if (conv && conv.lastMessageId) {
			// 调用 imService 的方法，并传入最后一条消息的ID
			imService.markConversationAsRead(conversationId, conv.lastMessageId);
		} else {
			console.warn(`[Vuex] 无法标记会话 ${conversationId} 为已读，因为未找到最后一条消息ID。`);
			// 即使没有最后一条消息ID，也尝试发送一个不带 ackId 的已读回执（见方案二）
			imService.markConversationAsRead(conversationId, null);
		}

		// 立即更新本地UI（这部分可以保留，用于即时反馈）
		commit('MARK_CONVERSATION_AS_READ', conversationId);
	},

	// 发送文本消息
	async sendTextMessage({
		state,
		commit,
		dispatch
	}, {
		to,
		content,
		chatType,
		ext,
		quoteInfo
	}) {
		if (!state.isConnected) {
			uni.showToast({
				title: 'IM未连接',
				icon: 'none'
			});
			return Promise.reject({
				errMsg: "IM not connected",
				code: -1
			});
		}

		const {
			localMessageForUI,
			sendPromise
		} = imService.sendTextMessage(to, content, chatType, ext, quoteInfo);

		// 1. 立即将本地消息添加到UI (通过mutation，如果聊天消息列表由Vuex管理)
		// 或者，聊天页面可以直接使用 localMessageForUI 更新自己的列表
		// 这里假设我们通过一个事件通知聊天页面添加本地消息
		imService.eventBus.$emit('im_local_message_added', {
			conversationId: chatType === 'singleChat' ? to : to, // 注意群聊时 to 是群ID
			message: localMessageForUI
		});

		// 2. 异步发送消息，并根据结果更新消息状态
		try {
			const result = await sendPromise; // { localId, serverId, message, status: 'sent' }
			// commit('UPDATE_MESSAGE_STATUS', {
			//     conversationId: chatType === 'singleChat' ? to : to,
			//     localId: result.localId,
			//     serverId: result.serverId,
			//     status: 'sent'
			// });
			imService.eventBus.$emit('im_message_status_updated', {
				conversationId: chatType === 'singleChat' ? to : to,
				localId: result.localId,
				serverId: result.serverId,
				status: 'sent'
			});

			// 确保会话的lastMessage也更新 (handleNewMessage 通常处理收到的消息)
			// 如果SDK不返回自己发送的消息，需要手动更新
			// 但通常配置为接收自己消息后，handleNewMessage会处理
			// dispatch('updateConversationWithMessage', { ...localMessageForUI, status: 'sent', id: result.serverId || result.localId });

			return result; // 返回给调用方
		} catch (error) { // error = { ...sdkError, localId, status: 'failed' }
			console.error("Vuex: Failed to send text message (action)", error);
			// commit('UPDATE_MESSAGE_STATUS', {
			//     conversationId: chatType === 'singleChat' ? to : to,
			//     localId: error.localId,
			//     status: 'failed'
			// });
			imService.eventBus.$emit('im_message_status_updated', {
				conversationId: chatType === 'singleChat' ? to : to,
				localId: error.localId,
				status: 'failed'
			});
			uni.showToast({
				title: '消息发送失败',
				icon: 'none'
			});
			throw error; // 继续抛出，让页面也能感知
		}
	},
	/**
	 * 发送图片消息 
	 * @param {object} payload - { to, filePath, chatType, ext }
	 */
	async sendImageMessage({
		state
	}, payload) {
		if (!state.isConnected) {
			uni.showToast({
				title: 'IM未连接',
				icon: 'none'
			});
			return Promise.reject({
				errMsg: "IM not connected"
			});
		}

		const {
			to,
			filePath,
			chatType,
			ext
		} = payload;

		// 1. 调用服务，立即获取UI对象和Promise
		const {
			localMessageForUI,
			sendPromise
		} = imService.sendImageMessage(to, filePath, chatType, ext);
		// 2. 立即派发事件，用于UI即时反馈
		// if (localMessageForUI) {
		imService.eventBus.$emit('im_local_message_added', {
			conversationId: to,
			message: localMessageForUI
		});
		// }

		// 3. 等待异步任务完成并处理结果
		try {
			const result = await sendPromise;
			// 4. 派发事件，更新消息最终状态
			imService.eventBus.$emit('im_message_status_updated', {
				conversationId: to,
				localId: result.localId,
				serverId: result.serverId,
				status: 'sent'
			});
			return result;
		} catch (error) {
			// 4. 派发事件，更新消息最终状态
			imService.eventBus.$emit('im_message_status_updated', {
				conversationId: to,
				localId: error.localId,
				status: 'failed'
			});
			uni.showToast({
				title: '图片发送失败',
				icon: 'none'
			});
			throw error;
		}
	},
	/**
	 * 发送视频消息 
	 * @param {object} payload - { to, filePath, duration, chatType, ext }
	 */
	async sendVideoMessage({
		state
	}, payload) {
		if (!state.isConnected) {
			uni.showToast({
				title: 'IM未连接',
				icon: 'none'
			});
			return Promise.reject({
				errMsg: "IM not connected"
			});
		}

		const {
			to,
			filePath,
			duration,
			chatType,
			ext
		} = payload;

		// 1. 调用服务，立即获取UI对象和Promise
		const {
			localMessageForUI,
			sendPromise
		} = imService.sendVideoMessage(to, filePath, duration, chatType, ext);

		// 2. 立即派发事件，用于UI即时反馈
		imService.eventBus.$emit('im_local_message_added', {
			conversationId: to,
			message: localMessageForUI
		});

		// 3. 等待异步任务完成并处理结果
		try {
			const result = await sendPromise;
			// 4. 派发事件，更新消息最终状态
			imService.eventBus.$emit('im_message_status_updated', {
				conversationId: to,
				localId: result.localId,
				serverId: result.serverId,
				status: 'sent',
				newContent: result.url // 关键：更新内容为网络URL
			});
			return result;
		} catch (error) {
			// 4. 派发事件，更新消息最终状态
			imService.eventBus.$emit('im_message_status_updated', {
				conversationId: to,
				localId: error.localId,
				status: 'failed'
			});
			uni.showToast({
				title: '视频发送失败',
				icon: 'none'
			});
			throw error;
		}
	},
	/**
	 * 发送语音消息 
	 * @param {object} payload - { to, filePath, duration, chatType, ext }
	 */
	async sendVoiceMessage({
		state
	}, payload) {
		if (!state.isConnected) {
			uni.showToast({
				title: 'IM未连接',
				icon: 'none'
			});
			return Promise.reject({
				errMsg: "IM not connected"
			});
		}

		const {
			to,
			filePath,
			duration,
			chatType,
			ext
		} = payload;

		const {
			localMessageForUI,
			sendPromise
		} = imService.sendVoiceMessage(to, filePath, duration, chatType, ext);

		imService.eventBus.$emit('im_local_message_added', {
			conversationId: to,
			message: localMessageForUI
		});

		try {
			const result = await sendPromise;
			imService.eventBus.$emit('im_message_status_updated', {
				conversationId: to,
				localId: result.localId,
				serverId: result.serverId,
				status: 'sent',
				newContent: result.url
			});
			return result;
		} catch (error) {
			imService.eventBus.$emit('im_message_status_updated', {
				conversationId: to,
				localId: error.localId,
				status: 'failed'
			});
			uni.showToast({
				title: '语音发送失败',
				icon: 'none'
			});
			throw error;
		}
	},
	/**
	 * 发起音视频通话
	 * @param {object} context - Vuex context
	 * @param {object} payload - { calleeId, callType }
	 */
	async makeCallAction({
		commit
	}, {
		calleeId,
		callType
	}) {
		if (!imService.isLoggedIn()) {
			throw new Error('IM未连接');
		}

		try {
			// 调用 imService 发起呼叫，它会返回导航到通话页面所需的数据
			const callParams = await imService.makeCall(calleeId, callType);

			// 导航到通话页面
			uni.navigateTo({
				url: `/pages/call/call?params=${encodeURIComponent(JSON.stringify(callParams))}`
			});
		} catch (error) {
			console.error('[Vuex makeCallAction] Error:', error);
			// 将错误向上抛出，以便UI层可以捕获并显示提示
			throw error;
		}
	},
	// (可选) 如果SDK不把自己的消息也通过onTextMessage返回，可能需要这个action
	updateConversationWithMessage({
		commit
	}, message) {
		commit('ADD_OR_UPDATE_CONVERSATION', message);
	}
};

const getters = {
	isImLoggedIn: state => state.isConnected && !!state.imUserId,
	totalUnreadCount: state => {
		return state.conversations.reduce((sum, conv) => sum + (conv.unreadCount || 0), 0);
	},
	getConversationById: (state) => (id) => {
		return state.conversations.find(conv => conv.id === id);
	}
};

export default {
	namespaced: true,
	state,
	mutations,
	actions,
	getters
};


// #endif





// #ifndef APP-PLUS || H5
// =========================================================================
//  此部分代码仅在非 App 和 H5 平台（如微信小程序）编译时生效
//  提供一个与完整版结构相同但功能为空的 Vuex 模块，
//  以避免在这些平台上因缺少 IM 功能而导致的其他代码报错。
// =========================================================================

// state: 提供一个最小化的状态树，确保对这些状态的访问不会返回 undefined
const state = {
	appKey: '',
	imConfig: null,
	isConnected: false, // IM连接状态，小程序中始终为 false
	isLoggingIn: false, // IM登录状态，小程序中始终为 false
	loginError: null, // IM登录错误，小程序中始终为 null
	imUserId: null, // 当前登录的IM用户ID
	imToken: null, // 环信登录凭证
	imAppToken: null, // 环信应用级Token

	// 核心UI相关状态，提供空数组作为默认值
	conversations: [], // 兼容旧的会话列表逻辑
	sessionList: [], // 后端同步的会话列表
	totalUnreadCount: 0, // 总未读消息数
};

// mutations: 提供空的 mutation，即使被调用也不会产生任何效果
const mutations = {
	SET_IM_CONFIG(state, config) {
		/* 空操作 */ },
	SET_CONNECTED(state, status) {
		state.isConnected = false;
	}, // 始终设为 false
	SET_LOGGING_IN(state, status) {
		state.isLoggingIn = false;
	}, // 始终设为 false
	SET_LOGIN_ERROR(state, error) {
		state.loginError = error;
	},
	SET_IM_USER(state, {
		userId,
		token
	}) {
		/* 空操作 */ },
	SET_IM_APP_TOKEN(state, token) {
		/* 空操作 */ },
	CLEAR_IM_USER(state) {
		state.imUserId = null;
		state.imToken = null;
		state.isConnected = false;
		state.imAppToken = null;
	},
	UPDATE_CONVERSATIONS(state, newConversations) {
		state.conversations = [];
	},
	SET_SESSION_LIST(state, sessions) {
		state.sessionList = [];
	},
	SET_TOTAL_UNREAD_COUNT(state, count) {
		state.totalUnreadCount = 0;
	},
	ADD_OR_UPDATE_CONVERSATION(state, message) {
		/* 空操作 */ },
	RESET_CONVERSATIONS(state) {
		state.conversations = [];
	},
	MARK_CONVERSATION_AS_READ(state, conversationId) {
		/* 空操作 */ },
	ADD_MESSAGE_TO_CONVERSATION(state, payload) {
		/* 空操作 */ },
	UPDATE_MESSAGE_STATUS(state, payload) {
		/* 空操作 */ }
};

// actions: 所有 action 都返回一个解决（resolve）或拒绝（reject）的 Promise，模拟异步行为
const actions = {
	// 初始化，直接返回成功，因为无需初始化
	initIMCore({
		commit
	}) {
		console.warn("IM功能在当前平台被禁用，initIMCore调用被忽略。");
		return Promise.resolve("IM in mock mode.");
	},

	// 进入会话，直接返回成功
	enterConversation({
		commit
	}, targetUserId) {
		console.warn("IM功能在当前平台被禁用，enterConversation调用被忽略。");
		return Promise.resolve();
	},

	// 获取会话列表，直接返回成功，列表为空
	fetchSessionList({
		commit
	}) {
		console.warn("IM功能在当前平台被禁用，fetchSessionList调用被忽略。");
		commit('SET_SESSION_LIST', []);
		return Promise.resolve();
	},

	// 获取总未读数，直接返回成功，数量为0
	fetchTotalUnreadCount({
		commit
	}) {
		console.warn("IM功能在当前平台被禁用，fetchTotalUnreadCount调用被忽略。");
		commit('SET_TOTAL_UNREAD_COUNT', 0);
		return Promise.resolve();
	},

	// 登录，直接返回失败
	login({
		commit
	}, payload) {
		console.warn("IM功能在当前平台被禁用，login调用被忽略。");
		const error = {
			errMsg: "IM功能在此平台不可用"
		};
		commit('SET_LOGIN_ERROR', error);
		return Promise.reject(error);
	},

	// 登出，直接返回成功
	logout({
		commit
	}) {
		console.warn("IM功能在当前平台被禁用，logout调用被忽略。");
		commit('CLEAR_IM_USER');
		return Promise.resolve();
	},

	// 处理新消息，直接返回成功
	handleNewMessage({
		commit
	}, message) {
		return Promise.resolve();
	},

	// 获取SDK会话列表，直接返回空数组
	fetchConversations({
		commit
	}) {
		commit('UPDATE_CONVERSATIONS', []);
		return Promise.resolve([]);
	},

	// 标记已读，直接返回成功
	markConversationRead({
		commit
	}, conversationId) {
		return Promise.resolve();
	},

	// 发送文本消息，直接返回失败
	sendTextMessage({
		commit
	}, payload) {
		return Promise.reject({
			errMsg: "IM功能在此平台不可用"
		});
	},

	// 发送图片消息，直接返回失败
	sendImageMessage({
		commit
	}, payload) {
		return Promise.reject({
			errMsg: "IM功能在此平台不可用"
		});
	},

	// 发送视频消息，直接返回失败
	sendVideoMessage({
		commit
	}, payload) {
		return Promise.reject({
			errMsg: "IM功能在此平台不可用"
		});
	},

	// 发送语音消息，直接返回失败
	sendVoiceMessage({
		commit
	}, payload) {
		return Promise.reject({
			errMsg: "IM功能在此平台不可用"
		});
	},

	// 发起音视频通话，直接返回失败
	makeCallAction({
		commit
	}, payload) {
		return Promise.reject({
			errMsg: "音视频通话功能在此平台不可用"
		});
	},
};

// getters: 提供默认的 getter 值
const getters = {
	isImLoggedIn: state => false,
	totalUnreadCount: state => 0,
	getConversationById: (state) => (id) => null,
};

export default {
	namespaced: true,
	state,
	mutations,
	actions,
	getters
};

// #endif